#include <math.h>

#ifdef QT_OPENGL_LIB
#include <QtOpenGL>
#else
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#endif


#include "SpriteBatchBMFont.h"


void SpriteBatchBMFont::letterFoundCallBack( TXML::Node *node, void *datato ) {
    SpriteBatchBMFont *tp = (SpriteBatchBMFont*)datato;
    if (strcmp( node->name(), "char")==0) {         // char-node found
        int index = atoi( node->getAttribute("id"));
        if (index>=0 && index<=255) {
            //qDebug("character %d found.", index );
            tp->asciiLetters[index].sx = atof( node->getAttribute("x")) / tp->m_sourceWScale;
            tp->asciiLetters[index].sy = atof( node->getAttribute("y")) / tp->m_sourceHScale;
            tp->asciiLetters[index].swidth = atof( node->getAttribute("width")) / tp->m_sourceWScale;
            tp->asciiLetters[index].sheight = atof( node->getAttribute("height")) / tp->m_sourceHScale;

            tp->asciiLetters[index].xoffset = atof( node->getAttribute("xoffset")) / tp->m_mainSize;
            tp->asciiLetters[index].yoffset = atof( node->getAttribute("yoffset")) / tp->m_mainSize;
            tp->asciiLetters[index].xadvance = atof( node->getAttribute("xadvance")) / tp->m_mainSize;

            tp->asciiLetters[index].xsize = atof( node->getAttribute("width")) / tp->m_mainSize;
            tp->asciiLetters[index].ysize = atof( node->getAttribute("height")) / tp->m_mainSize;

        }
    } else
        if (strcmp( node->name(), "common") == 0) {
            tp->m_sourceWScale = atof( node->getAttribute("scaleW"));
            tp->m_sourceHScale = atof( node->getAttribute("scaleH"));
            //qDebug("common-node found. WidthScale: %f HeightScale: %f", tp->m_sourceWScale, tp->m_sourceHScale );
        } else
            if (strcmp( node->name(), "info") == 0) {
                tp->m_mainSize = atof( node->getAttribute("size"));
                //qDebug("MainSize is: %f", tp->m_mainSize );
            }



}

SpriteBatchBMFont::SpriteBatchBMFont(
        QString descFileName,
        QString fontImageName ) {
    QFile file(descFileName);
    if (file.open(QFile::ReadOnly)) {
        TXML::Reader *reader = new TXML::Reader( letterFoundCallBack, this );
        TXML::Node *node = reader->scanXML( file );
        if (node) {

            delete node;
        }
        delete reader;
    }


    // Load the page-texture
    QImage load = QImage( fontImageName );

    if (load.isNull()==false) {
        // Create a texture out of it
        glGenTextures(1, &m_fontTexture);
        glBindTexture(GL_TEXTURE_2D, m_fontTexture);
        GLuint* pTexData = new GLuint[load.width() * load.height()];
        GLuint* sdata = (GLuint*)load.bits();
        GLuint* tdata = pTexData;

        for (int y=0; y<load.height(); y++)
            for (int x=0; x<load.width(); x++) {
                *tdata = ((*sdata&255) << 16) | (((*sdata>>8)&255) << 8)
                        | (((*sdata>>16)&255) << 0) | (((*sdata>>24)&255) << 24);

                sdata++;
                tdata++;
            };

#ifndef Q_OS_WIN
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, load.width(), load.height(), 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, pTexData);

        delete [] pTexData;
    }
}


SpriteBatchBMFont::~SpriteBatchBMFont() {
    glDeleteTextures(1, &m_fontTexture );
}


void SpriteBatchBMFont::writeText( SpriteBatch *sb, const char *string, float x, float y, float size,
                                   float angle, float r, float g, float b,float a) {
    LetterInfo *l;
    SpriteDrawInfo sdi;
    sdi.textureHandle = m_fontTexture;
    sb->flushSprites();
    sdi.setColor(r,g,b,a);

    sdi.angle = angle;

    float xvec = cosf( angle );
    float yvec = sinf( angle );
    float tx,ty;

    float halfsize = size/2.0f;
    float xinc = 0.0f;

    while (*string) {
        l = &asciiLetters[ *string ];
        sdi.setSourceRect(l->sx, l->sy, l->swidth, l->sheight );
        sdi.setScale(size*l->xsize, size*l->ysize );

        tx = xinc+(l->xadvance+l->xoffset)*halfsize;
        ty = -halfsize + (l->ysize)*halfsize + l->yoffset*size;
        sdi.setTargetPos(x+tx*xvec+ty*yvec,y+tx*(-yvec) + ty*xvec);
        sb->draw(&sdi);
        xinc+=l->xadvance*size;
        string++;
    }

}



float SpriteBatchBMFont::getTextLength( const char *string, float size ) {
    LetterInfo *l;
    float x = 0.0f;
    while (*string) {
        l = &asciiLetters[ *string ];
        x+=l->xadvance*size;
        string++;
    }
    return x;
}
